/*
 * Copyright© 2003-2019 浙江汇信科技有限公司, All Rights Reserved.
 */
package com.icinfo.cloud.provider.punish.ucase.casemain.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.icinfo.cloud.common.security.util.UserUtil;
import com.icinfo.cloud.provider.common.constant.Constant;
import com.icinfo.cloud.provider.common.enums.DocumentKindEnum;
import com.icinfo.cloud.provider.common.exception.BusinessException;
import com.icinfo.cloud.provider.common.utils.BaseUtil;
import com.icinfo.cloud.provider.punish.common.documentoperate.enums.DocumentRecordStatusEnum;
import com.icinfo.cloud.provider.punish.common.documentoperate.service.IStageDocCommonOperateService;
import com.icinfo.cloud.provider.punish.config.mapper.ConfigCaseTemporaryDocumentMapper;
import com.icinfo.cloud.provider.punish.config.model.ConfigBusiParamDocumentInfo;
import com.icinfo.cloud.provider.punish.config.service.IConfigBusiParamDocumentInfoService;
import com.icinfo.cloud.provider.punish.ucase.casemain.dto.AppendixDto;
import com.icinfo.cloud.provider.punish.ucase.casemain.dto.CaseTemporaryRecordQueryDto;
import com.icinfo.cloud.provider.punish.ucase.casemain.dto.CaseTemporarySaveDto;
import com.icinfo.cloud.provider.punish.ucase.casemain.enums.HandlePersonTypeEnum;
import com.icinfo.cloud.provider.punish.ucase.casemain.mapper.*;
import com.icinfo.cloud.provider.punish.ucase.casemain.model.*;
import com.icinfo.cloud.provider.punish.ucase.casemain.service.*;
import com.icinfo.cloud.provider.punish.ucase.casemain.vo.CaseMainInfoVo;
import com.icinfo.cloud.workflow.work.model.WorkFlowRollAssistMainInfo;
import com.icinfo.cloud.workflow.work.service.IWorkFlowRollAssistMainInfoService;
import com.icinfo.cloud.xzcf.provider.member.userinfo.dto.UserDTO;
import com.icinfo.framework.core.service.support.MyBatisServiceSupport;
import com.icinfo.framework.mybatis.mapper.entity.Example;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 描述: 文书内容暂存表 case_temporary_record 对应的Service接口实现类.<br>
 *
 * @author framework generator
 * @date 2022年03月24日
 */
@Service
public class CaseTemporaryRecordServiceImpl extends MyBatisServiceSupport implements ICaseTemporaryRecordService {
    /**
     * 日志记录器
     */
    private static final Logger logger = LoggerFactory.getLogger(CaseTemporaryRecordServiceImpl.class);

    @Resource
    private CaseTemporaryRecordMapper caseTemporaryRecordMapper;
    @Resource
    private CaseDocumentRecordMapper caseDocumentRecordMapper;
    @Resource
    private ICaseDocumentRecordService caseDocumentRecordService;
    @Resource
    private ICaseMainInfoService caseMainInfoService;
    @Resource
    private CaseHandlePersonRecordMapper caseHandlePersonRecordMapper;
    @Resource
    private CaseReasonMainRecordMapper caseReasonMainRecordMapper;
    @Resource
    private ICasePartiesRecordService casePartiesRecordService;
    @Resource
    private ICaseAppendixRecordService caseAppendixRecordService;
    @Resource
    private IConfigBusiParamDocumentInfoService configBusiParamDocumentInfoService;
    @Autowired
    private IWorkFlowRollAssistMainInfoService workFlowRollAssistMainInfoService;
    @Resource
    private  IStageDocCommonOperateService stageDocCommonOperateService;
    @Resource
    private ConfigCaseTemporaryDocumentMapper configCaseTemporaryDocumentMapper;
    @Resource
    private ICaseMainDetailInfoService caseMainDetailInfoService;
    /**
     * 暂存数据
     *
     * @param saveDto 保存dto
     * @return boolean
     * @author shishengyao
     * @date 2022/07/13
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveTemporary(CaseTemporarySaveDto saveDto) {
        //1.保存文书暂存数据
        //2.设置文书为草稿状态
        if (saveDto == null) {
            return false;
        }
        UserDTO userDTO = UserUtil.getUserInfo();
        String caseId = saveDto.getCaseId();
        String documentCatalogCode =saveDto.getDocumentCatalogCode();
        String partyId = saveDto.getPartyId();
        //增加送达当事人id处理
        if (ObjectUtils.isEmpty(partyId)) {
            if (caseMainInfoService.validateIsNeedPassPartyId(null, caseId)) {
                throw new BusinessException("多当事人分别处罚时请指定当事人id");
            }
            Map<String, String> map = casePartiesRecordService.getCasePartyIdNameInfo(caseId);
            partyId = map.get("partyId");
        }
        if(saveDto.getDataMap()==null){
            return false;
        }
        //查询案件信息
        CaseMainInfoVo caseMainInfoVo = caseMainInfoService.getCaseMainInfo(caseId);
        ConfigBusiParamDocumentInfo busiParamDocumentInfo = configBusiParamDocumentInfoService.getConfigBusiParamDocumentInfoByBusiParamIdAndCode(caseMainInfoVo.getBusiParamId(), saveDto.getDocumentCatalogCode());

        //  听证类与非听证类处罚告知文书暂存时，需要判断是否已经存在相关的文书（听证类与非听证类），如果已经存在则要删除另一种处罚告知文书的暂存数据
        if(Objects.equals(busiParamDocumentInfo.getDocumentKindCode(), DocumentKindEnum.DOC_KIND_CFGZSPB.getCode())){
            dealPunishInformIsHearingDocument(caseId, String.valueOf(saveDto.getDataMap().get("XZCFGZS_TZL_SFFHTZTJ")), saveDto.getDocumentCatalogCode(), busiParamDocumentInfo.getRelationDocumentCatalogCode());
        }

        //查询是否存在记录，存在删除
        removeTemporary(caseId, documentCatalogCode, partyId);
        //查询并更新文书记录表的文书内容
        String documentId = saveDto.getDocumentId();
        //查询并更新文书记录表的文书内容
        CaseDocumentRecord caseDocumentRecord = null;
        if(DocumentKindEnum.DOC_KIND_DK1BZGZSPB.getCode().equals(busiParamDocumentInfo.getDocumentKindCode()) || DocumentKindEnum.DOC_KIND_DK2BZGZTZS.getCode().equals(busiParamDocumentInfo.getDocumentKindCode())){
            if (ObjectUtil.isNotEmpty(documentId)) {
                caseDocumentRecord=caseDocumentRecordMapper.selectByPrimaryKey(documentId);
            }else {
                //如果是补正/更正，多次暂存，则查询出来暂存记录
                Example example = new Example(CaseDocumentRecord.class);
                example.createCriteria().andEqualTo("documentRecordStatus", DocumentRecordStatusEnum.DRAFT.getCode())
                        .andEqualTo("relationDocumentId", saveDto.getRelationDocumentId())
                        .andEqualTo("documentCatalogCode", saveDto.getDocumentCatalogCode());
                List<CaseDocumentRecord> list = caseDocumentRecordMapper.selectByExample(example);
                if (ObjectUtil.isNotEmpty(list)) {
                    caseDocumentRecord = list.get(Constant.INTEGER_0);
                }
            }
        } else {
            if (ObjectUtil.isNotEmpty(documentId)) {
                caseDocumentRecord=caseDocumentRecordMapper.selectByPrimaryKey(documentId);
                if (!documentCatalogCode.equals(caseDocumentRecord.getDocumentCatalogCode())){
                    caseDocumentRecord = caseDocumentRecordService.getCaseDocumentRecord(caseId, documentCatalogCode, partyId);
                }
            } else {
                caseDocumentRecord = caseDocumentRecordService.getCaseDocumentRecord(caseId, documentCatalogCode, partyId);
            }
        }

        if (ObjectUtil.isNotEmpty(caseDocumentRecord)) {

            CaseDocumentRecord newCaseDocumentRecord = new CaseDocumentRecord();
            newCaseDocumentRecord.setId(caseDocumentRecord.getId());
            newCaseDocumentRecord.setDocumentContent(saveDto.getDataMap().toJSONString());
            //设置文书为草稿状态
            newCaseDocumentRecord.setDocumentRecordStatus(DocumentRecordStatusEnum.DRAFT.getCode());
            newCaseDocumentRecord.setRelationDocumentId(saveDto.getRelationDocumentId());

            caseDocumentRecordMapper.updateByPrimaryKeySelective(newCaseDocumentRecord);
        }else {
            //暂存数据保存文书记录表
            CaseDocumentRecord insertRecord=new CaseDocumentRecord();
            insertRecord.setId(BaseUtil.createUid());
            insertRecord.setCaseId(caseId);
            insertRecord.setPartyId(partyId);
            insertRecord.setDocumentCatalogCode(documentCatalogCode);
            if(StringUtils.isNotBlank(saveDto.getCaseAssistId())){
                WorkFlowRollAssistMainInfo workFlowRollAssistMainInfo = workFlowRollAssistMainInfoService.doGetWorkFlowRollAssistMainInfoById(saveDto.getCaseAssistId());
                if(ObjectUtils.isEmpty(workFlowRollAssistMainInfo)){
                    throw new BusinessException("当前子流程缺失！");
                }else {
                    insertRecord.setCaseStageName(workFlowRollAssistMainInfo.getWorkAssistCurrentStageName());
                    insertRecord.setCaseStageCode(workFlowRollAssistMainInfo.getWorkAssistCurrentStageCode());
                    insertRecord.setCaseLinkCode(workFlowRollAssistMainInfo.getWorkAssistCurrentLinkCode());
                    insertRecord.setCaseLinkName(workFlowRollAssistMainInfo.getWorkAssistCurrentLinkName());
                    insertRecord.setCaseAssistId(saveDto.getCaseAssistId());
                }
            }else {
                insertRecord.setCaseStageName(caseMainInfoVo.getCaseCurrentStageName());
                insertRecord.setCaseStageCode(caseMainInfoVo.getCaseCurrentStageCode());
                insertRecord.setCaseLinkCode(caseMainInfoVo.getCaseCurrentLinkCode());
                insertRecord.setCaseLinkName(caseMainInfoVo.getCaseCurrentLinkName());
            }
            insertRecord.setDocumentContent(saveDto.getDataMap().toJSONString());
            insertRecord.setCreateUserId(userDTO.getUserId().toString());
            insertRecord.setCreateUserName(userDTO.getRealName());
            insertRecord.setDocumentCreateTime(LocalDateTime.now());
            insertRecord.setDocumentRecordStatus(DocumentRecordStatusEnum.DRAFT.getCode());
            insertRecord.setRelationDocumentId(saveDto.getRelationDocumentId());
            //获取模板code
            String templateCode = stageDocCommonOperateService.getTemplateCodeByDocumentCatalogCode(saveDto.getDocumentCatalogCode(), caseId, saveDto.getDataMap(),partyId);
            insertRecord.setDocumentTemplateCode(templateCode);
            //判断是补正/更正

            if(DocumentKindEnum.DOC_KIND_DK1BZGZSPB.getCode().equals(busiParamDocumentInfo.getDocumentKindCode()) || DocumentKindEnum.DOC_KIND_DK2BZGZTZS.getCode().equals(busiParamDocumentInfo.getDocumentKindCode())){
                CaseDocumentRecord relationRecord = caseDocumentRecordMapper.selectByPrimaryKey(saveDto.getRelationDocumentId());
                if(relationRecord != null){
                    insertRecord.setCaseStageName(relationRecord.getCaseStageName());
                    insertRecord.setCaseStageCode(relationRecord.getCaseStageCode());
                    insertRecord.setCaseLinkCode(relationRecord.getCaseLinkCode());
                    insertRecord.setCaseLinkName(relationRecord.getCaseLinkName());
                }
            }
            caseDocumentRecordMapper.insertSelective(insertRecord);
        }
        //保存附件（如果在配置表中，则表示暂存的时候，不需要操作附件）
        List<String> configCaseTemporaryDocuments = configCaseTemporaryDocumentMapper.selectDocumentCatalogCodeAll();
        if(!configCaseTemporaryDocuments.contains(documentCatalogCode)){
            caseAppendixRecordService.removeCaseAppendixRecordByCaseIdAndCatalogCodeAndPartyId(caseId,documentCatalogCode,partyId);
            if (!ObjectUtils.isEmpty(saveDto.getAppendixList())) {
                List<AppendixDto> appendixList = saveDto.getAppendixList();
                for (AppendixDto appendixDto : appendixList) {
                    CaseAppendixRecord record = new CaseAppendixRecord();
                    record.setCaseId(saveDto.getCaseId());
                    record.setAppendixUrl(appendixDto.getAppendixUrl());
                    record.setAppendixTypeId(appendixDto.getAppendixTypeId());
                    record.setAppendixName(appendixDto.getAppendixName());
                    record.setDocumentCatalogCode(documentCatalogCode);
                    record.setId(BaseUtil.createUid());
                    caseAppendixRecordService.saveCaseAppendixRecord(record);
                }
            }
        }
        //保存到暂存表
        CaseTemporaryRecord record = new CaseTemporaryRecord();
        record.setId(BaseUtil.createUid());
        record.setCaseId(caseId);
        record.setContent(JSON.toJSONString(saveDto));
        record.setAddUser(userDTO.getLoginName());
        record.setCreateTime(LocalDateTime.now());
        record.setDocumentCatalogCode(saveDto.getDocumentCatalogCode());
        //新增当事人id存储
        record.setPartyId(partyId);
        int effect = caseTemporaryRecordMapper.insertSelective(record);
        if (effect > 0) {
            return true;
        }
        return false;
    }

    /**
     * 处理处罚告知 是否听证出现变化导致存在多个 处罚告知书的问题
     * @param caseId 案件id
     * @param isHearing 此次暂存传递的是否听证
     * @param documentCatalogCode 审批表的文书目录编码documentCatalogCode
     * @param relationDocumentCatalogCode 审批表的关联文书目录编码relationDocumentCatalogCode
     */
    private void dealPunishInformIsHearingDocument(String caseId, String isHearing, String documentCatalogCode, String relationDocumentCatalogCode){
        //查询是否已经有暂存的处罚审批表
        Example documentRecordExample = new Example(CaseDocumentRecord.class);
        Example.Criteria documentRecordCriteria = documentRecordExample.createCriteria();
        documentRecordCriteria.andEqualTo("caseId", caseId).andEqualTo("documentCatalogCode", documentCatalogCode)
                .andIn("documentRecordStatus", Arrays.asList(DocumentRecordStatusEnum.NORMAL.getCode(), DocumentRecordStatusEnum.DRAFT.getCode()));
        List<CaseDocumentRecord> caseDocumentRecords = caseDocumentRecordMapper.selectByExample(documentRecordExample);
        if (CollectionUtil.isEmpty(caseDocumentRecords)){
            //如果没有处罚告知审批表记录，则不进行一下操作
            return;
        }
        JSONObject jsonObject = JSONObject.parseObject(caseDocumentRecords.get(0).getDocumentContent());
        //判断是否听证是否发生了变化
        if (!Objects.equals(isHearing, String.valueOf(jsonObject.get("XZCFGZS_TZL_SFFHTZTJ")))){
            //是否听证isHearing发生变化时删除之前保存的文书--不处理的话会生成两种告知书
            if (!ObjectUtils.isEmpty(relationDocumentCatalogCode)) {
                relationDocumentCatalogCode = documentCatalogCode + "," + relationDocumentCatalogCode;
                List<String> deleteDocumentCatalogCode = Arrays.asList(relationDocumentCatalogCode.split(","));
                //删除文书记录
                documentRecordExample.clear();
                Example.Criteria deleteDocumentRecordCriteria = documentRecordExample.createCriteria();
                deleteDocumentRecordCriteria.andEqualTo("caseId", caseId).andIn("documentCatalogCode", deleteDocumentCatalogCode)
                        .andIn("documentRecordStatus", Arrays.asList(DocumentRecordStatusEnum.NORMAL.getCode(), DocumentRecordStatusEnum.DRAFT.getCode()));
                //删除暂存表的记录
                caseDocumentRecordMapper.deleteByExample(documentRecordExample);
                Example temporaryRecordExample = new Example(CaseTemporaryRecord.class);
                Example.Criteria temporaryRecordCriteria = temporaryRecordExample.createCriteria();
                temporaryRecordCriteria.andEqualTo("caseId", caseId).andIn("documentCatalogCode", deleteDocumentCatalogCode);
                caseTemporaryRecordMapper.deleteByExample(temporaryRecordExample);
            }
        }
    }

    /**
     * 获取暂存数据
     *
     * @param caseId
     * @param documentCatalogCode
     * @return
     */
    @Override
    public CaseTemporaryRecord getRecord(String caseId, String documentCatalogCode,String partyId) {

        Example example = new Example(CaseTemporaryRecord.class);
        if(StringUtils.isBlank(partyId)){
            example.createCriteria().andEqualTo("caseId", caseId).andEqualTo("documentCatalogCode", documentCatalogCode);
        }else{
            example.createCriteria().andEqualTo("caseId", caseId).andEqualTo("documentCatalogCode", documentCatalogCode).andEqualTo("partyId",partyId);
        }
        example.orderBy("createTime").desc();
        List<CaseTemporaryRecord> list = caseTemporaryRecordMapper.selectByExample(example);
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    /**
     * 更新办案人
     * @author lxj
     * @date  2022/2/24
     * @param jsonObject
     * @return void
     **/
    private void updateHandlePerson(JSONObject jsonObject ,UserDTO userInfo){
        String caseId = jsonObject.getString("caseId");

        Example example  = new Example(CaseHandlePersonRecord.class);
        example.createCriteria().andEqualTo("caseId",caseId).andEqualTo("status", Constant.STRING_1);
        List<CaseHandlePersonRecord> list = caseHandlePersonRecordMapper.selectByExample(example);
        if(list!=null&&list.size()>0){
            caseHandlePersonRecordMapper.deleteByExample(example);
        }
        // 添加办案人员表--登录人为主办人
        CaseHandlePersonRecord handlePersonRecord = new CaseHandlePersonRecord();
        handlePersonRecord.setCaseId(caseId);
        handlePersonRecord.setHandlePersonName(userInfo.getRealName());
        handlePersonRecord.setHandlePersonId(userInfo.getUserId().toString());
        handlePersonRecord.setHandleDeptCode(userInfo.getDeptCode());
        handlePersonRecord.setHandleDeptName(userInfo.getDeptName());
        handlePersonRecord.setHandleOrgCode(userInfo.getOrgCode());
        handlePersonRecord.setHandleOrgName(userInfo.getOrgName());
        handlePersonRecord.setHandleDeptTel(userInfo.getTelPhone());
        handlePersonRecord.setHandlePersonType(HandlePersonTypeEnum.MAIN.getCode());
        handlePersonRecord.setId(BaseUtil.createUid());
        handlePersonRecord.setStatus(Constant.STRING_1);
        handlePersonRecord.setAddTime(new Date());
        //主办人
        caseHandlePersonRecordMapper.insertSelective(handlePersonRecord);
        //5.1 添加协办
        handlePersonRecord.setHandlePersonName(jsonObject.getString("handlePersonName"));
        handlePersonRecord.setHandlePersonType(HandlePersonTypeEnum.ASSIST.getCode());
        handlePersonRecord.setHandlePersonId(jsonObject.getString("handlePersonId"));
        handlePersonRecord.setId(BaseUtil.createUid());
        handlePersonRecord.setStatus(Constant.STRING_1);
        handlePersonRecord.setAddTime(new Date());
        caseHandlePersonRecordMapper.insertSelective(handlePersonRecord);
    }

    /*
     * 更新或添加案由表
     */
    private void updateReasonRecord(JSONObject jsonObject) {
        String caseId = jsonObject.getString("caseId");
        //之前老数据删除
        Example example = new Example(CaseReasonMainRecord.class);
        example.createCriteria().andEqualTo("caseId", caseId);
        caseReasonMainRecordMapper.deleteByExample(example);

        CaseReasonMainRecord reasonMainRecord = new CaseReasonMainRecord();
        reasonMainRecord.setCaseId(caseId);
        reasonMainRecord.setCreateTime(LocalDateTime.now());
        reasonMainRecord.setId(BaseUtil.createUid());
        reasonMainRecord.setCaseReasonCode(StringUtils.isEmpty(jsonObject.getString("caseReasonCode"))?"-":jsonObject.getString("caseReasonCode"));
        reasonMainRecord.setCaseReasonName(StringUtils.isEmpty(jsonObject.getString("caseReason"))?"-":jsonObject.getString("caseReason"));

        reasonMainRecord.setStatus(Constant.STRING_1);
        caseReasonMainRecordMapper.insertSelective(reasonMainRecord);
    }


    /**
     * 删除文书暂存记录--通用方法
     * @param caseId              用例id
     * @param documentCatalogCode 文件目录的代码
     * @param partyId 当事人id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeTemporary(String caseId, String documentCatalogCode, String partyId) {
        Example example = new Example(CaseTemporaryRecord.class);
        example.createCriteria().andEqualTo("caseId", caseId).andEqualTo("documentCatalogCode", documentCatalogCode).andEqualTo("partyId", partyId);
        return caseTemporaryRecordMapper.deleteByExample(example);
    }

    /***
     * @Author: zhengqiang
     * @Date: 2022/5/13
     * @Description: 获取暂存数据
     * @param: caseTemporaryRecordQueryDto
     * @return: com.icinfo.cloud.provider.punish.ucase.casemain.model.CaseTemporaryRecord
     **/
    @Override
    public CaseTemporaryRecord getRecord(CaseTemporaryRecordQueryDto caseTemporaryRecordQueryDto) {
        String caseId = caseTemporaryRecordQueryDto.getCaseId();
        String partyId = caseTemporaryRecordQueryDto.getPartyId();
        String documentCatalogCode = caseTemporaryRecordQueryDto.getDocumentCatalogCode();
        //增加送达当事人id处理
        if (ObjectUtils.isEmpty(partyId)) {
            if (caseMainInfoService.validateIsNeedPassPartyId(null, caseId)) {
                throw new BusinessException("多当事人分别处罚时请指定当事人id");
            }
            Map<String, String> map = casePartiesRecordService.getCasePartyIdNameInfo(caseId);
            partyId = map.get("partyId");
        }

        Example example = new Example(CaseTemporaryRecord.class);
        example.createCriteria().andEqualTo("caseId", caseId)
                .andEqualTo("documentCatalogCode", documentCatalogCode)
                .andEqualTo("partyId", partyId);
        example.orderBy("createTime").desc();
        List<CaseTemporaryRecord> list = caseTemporaryRecordMapper.selectByExample(example);
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public int removeTemporary(String caseId, String documentCatalogCode) {
        Example example = new Example(CaseTemporaryRecord.class);
        example.createCriteria().andEqualTo("caseId", caseId).andEqualTo("documentCatalogCode", documentCatalogCode);
        return caseTemporaryRecordMapper.deleteByExample(example);
    }

    /**
     * 描述：移除所有案件相关的暂存数据
     *
     * @param caseId 案件id
     * @return int 移除成功记录数
     * @author xiangyuyu
     * @date 2022-07-07 17:28
     */
    @Override
    public int removeAllTemporaryWithCaseId(String caseId) {
        Example example = new Example(CaseTemporaryRecord.class);
        example.createCriteria().andEqualTo("caseId", caseId);
        return caseTemporaryRecordMapper.deleteByExample(example);
    }

}

